﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Text;
using MicropleSoft.WmsApp.Library.Security;
using MicropleSoft.WmsApp.Library.ServiceFacade;

namespace MicropleSoft.WmsApp.Library.ClientProxy
{
    public static class ClientProxyFactory
    {
        private static ChannelFactory<IServiceFacadeChannel> _factoryFacade;

        public static IServiceFacadeChannel GetServiceFacadeClient()
        {
            var channel = CreateServiceChannel<IServiceFacadeChannel>(GetFacadeChannelFactory().CreateChannel());
            return channel;
        }
   
        private static T CreateServiceChannel<T>(IClientChannel proxy)
        {
            if (UserSession.IsLogOn)
            {
                var scope = new OperationContextScope(proxy);
                var messageHeader = new MessageHeader<String>(UserSession.Token);
                var untypedHeader = messageHeader.GetUntypedHeader("token", "ns");
                OperationContext.Current.OutgoingMessageHeaders.Add(untypedHeader);
            }
            return (T)proxy;
        }

        private static ChannelFactory<IServiceFacadeChannel> GetFacadeChannelFactory()
        {
            if (_factoryFacade == null)
            {
                _factoryFacade = new ChannelFactory<IServiceFacadeChannel>("BasicHttpBinding_IServiceFacade");
                AttachServiceBehavior(_factoryFacade);
            }
            return _factoryFacade;
        }

        private static void AttachServiceBehavior<T>(ChannelFactory<T> channelFactory)
        {
            //找到程序集的其中任何一个class，确定程序集
            var type = typeof (ClientRuntime);
            //实例化internal类，通过反射
            var instance =
                type.Assembly.CreateInstance("System.ServiceModel.Dispatcher.DataContractSerializerServiceBehavior",
                                             true,
                                             BindingFlags.CreateInstance | BindingFlags.Instance |
                                             BindingFlags.NonPublic, null, new object[] {false, Int32.MaxValue}, null,
                                             null);
            //转换成终结点的行为接口
            var behavior = instance as IEndpointBehavior;
            if (behavior != null)
            {
                //插入到通道工厂的终结点行为集合中
                channelFactory.Endpoint.Behaviors.Add(behavior);
            }
        }
    }
    
}
